home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
366_01
/
ue311c1.arc
/
EVAL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-30
|
35KB
|
1,382 lines
/* EVAL.C: Expresion evaluation functions for
MicroEMACS
written 1986 by Daniel Lawrence */
#include <stdio.h>
#include "estruct.h"
#include "eproto.h"
#include "edef.h"
#include "elang.h"
#include "evar.h"
PASCAL NEAR varinit() /* initialize the user variable list */
{
register int i;
for (i=0; i < MAXVARS; i++)
uv[i].u_name[0] = 0;
}
PASCAL NEAR varclean() /* initialize the user variable list */
{
register int i;
for (i=0; i < MAXVARS; i++)
if (uv[i].u_name[0] != 0)
free(uv[i].u_value);
}
char *PASCAL NEAR gtfun(fname) /* evaluate a function */
char *fname; /* name of function to evaluate */
{
register int fnum; /* index to function to eval */
register int arg; /* value of some arguments */
char arg1[NSTRING]; /* value of first argument */
char arg2[NSTRING]; /* value of second argument */
char arg3[NSTRING]; /* value of third argument */
static char result[2 * NSTRING]; /* string result */
#if ENVFUNC
char *getenv(); /* get environment string */
#endif
/* look the function up in the function table */
fname[3] = 0; /* only first 3 chars significant */
mklower(fname); /* and let it be upper or lower case */
fnum = binary(fname, funval, NFUNCS);
/* return errorm on a bad reference */
if (fnum == -1)
return(errorm);
/* if needed, retrieve the first argument */
if (funcs[fnum].f_type >= MONAMIC) {
if (macarg(arg1) != TRUE)
return(errorm);
/* if needed, retrieve the second argument */
if (funcs[fnum].f_type >= DYNAMIC) {
if (macarg(arg2) != TRUE)
return(errorm);
/* if needed, retrieve the third argument */
if (funcs[fnum].f_type >= TRINAMIC)
if (macarg(arg3) != TRUE)
return(errorm);
}
}
/* and now evaluate it! */
switch (fnum) {
case UFADD: return(int_asc(asc_int(arg1) + asc_int(arg2)));
case UFSUB: return(int_asc(asc_int(arg1) - asc_int(arg2)));
case UFTIMES: return(int_asc(asc_int(arg1) * asc_int(arg2)));
case UFDIV: return(int_asc(asc_int(arg1) / asc_int(arg2)));
case UFMOD: return(int_asc(asc_int(arg1) % asc_int(arg2)));
case UFNEG: return(int_asc(-asc_int(arg1)));
case UFCAT: strcpy(result, arg1);
return(strcat(result, arg2));
case UFLEFT: return(bytecopy(result, arg1, asc_int(arg2)));
case UFRIGHT: arg = asc_int(arg2);
if (arg > strlen(arg1))
arg = strlen(arg1);
return(strcpy(result,
&arg1[strlen(arg1) - arg]));
case UFMID: arg = asc_int(arg2);
if (arg > strlen(arg1))
arg = strlen(arg1);
return(bytecopy(result, &arg1[arg-1],
asc_int(arg3)));
case UFNOT: return(ltos(stol(arg1) == FALSE));
case UFEQUAL: return(ltos(asc_int(arg1) == asc_int(arg2)));
case UFLESS: return(ltos(asc_int(arg1) < asc_int(arg2)));
case UFGREATER: return(ltos(asc_int(arg1) > asc_int(arg2)));
case UFGROUP:
if ((arg = asc_int(arg1)) < 0 || arg >= MAXGROUPS)
return(bytecopy(result, errorm, NSTRING * 2));
#if MAGIC
return(bytecopy(result, fixnull(grpmatch[arg]),
NSTRING * 2));
#else
if (arg == 0)
bytecopy(result, patmatch, NSTRING * 2);
else
result[0] = '\0';
return(result);
#endif
case UFSEQUAL: return(ltos(strcmp(arg1, arg2) == 0));
case UFSLESS: return(ltos(strcmp(arg1, arg2) < 0));
case UFSGREAT: return(ltos(strcmp(arg1, arg2) > 0));
case UFIND: return(strcpy(result, fixnull(getval(arg1))));
case UFAND: return(ltos(stol(arg1) && stol(arg2)));
case UFOR: return(ltos(stol(arg1) || stol(arg2)));
case UFLENGTH: return(int_asc(strlen(arg1)));
case UFUPPER: return(mkupper(arg1));
case UFLOWER: return(mklower(arg1));
case UFTRUTH: return(ltos(asc_int(arg1) == 42));
case UFASCII: return(int_asc((int)arg1[0]));
case UFCHR: result[0] = asc_int(arg1);
result[1] = 0;
return(result);
case UFGTCMD: cmdstr(getcmd(), result);
return(result);
case UFGTKEY: result[0] = tgetc();
result[1] = 0;
return(result);
case UFRND: return(int_asc((ernd() % absv(asc_int(arg1))) + 1));
case UFABS: return(int_asc(absv(asc_int(arg1))));
case UFSINDEX: return(int_asc(sindex(arg1, arg2)));
case UFENV:
#if ENVFUNC
return(fixnull(getenv(arg1)));
#else
return("");
#endif
case UFBIND: return(transbind(arg1));
case UFEXIST: return(ltos(fexist(arg1)));
case UFFIND:
return(fixnull(flook(arg1, TRUE)));
case UFBAND: return(int_asc(asc_int(arg1) & asc_int(arg2)));
case UFBOR: return(int_asc(asc_int(arg1) | asc_int(arg2)));
case UFBXOR: return(int_asc(asc_int(arg1) ^ asc_int(arg2)));
case UFBNOT: return(int_asc(~asc_int(arg1)));
case UFXLATE: return(xlat(arg1, arg2, arg3));
case UFTRIM: return(trimstr(arg1));
case UFSLOWER: return(setlower(arg1, arg2), "");
case UFSUPPER: return(setupper(arg1, arg2), "");
case UFISNUM: return(ltos(is_num(arg1)));
}
meexit(-11); /* never should get here */
}
char *PASCAL NEAR gtusr(vname) /* look up a user var's value */
char *vname; /* name of user variable to fetch */
{
register int vnum; /* ordinal number of user var */
register char *vptr; /* temp pointer to function value */
/* limit comparisons to significant length */
if (strlen(vname) >= NVSIZE) /* "%" counts, but is not passed */
vname[NVSIZE-1] = '\0';
/* scan the list looking for the user var name */
for (vnum = 0; vnum < MAXVARS; vnum++) {
if (uv[vnum].u_name[0] == 0)
return(errorm);
if (strcmp(vname, uv[vnum].u_name) == 0) {
vptr = uv[vnum].u_value;
if (vptr)
return(vptr);
else
return(errorm);
}
}
/* return errorm if we run off the end */
return(errorm);
}
char *PASCAL NEAR funval(i)
int i;
{
return(funcs[i].f_name);
}
char *PASCAL NEAR envval(i)
int i;
{
return(envars[i]);
}
PASCAL NEAR binary(key, tval, tlength)
char *key; /* key string to look for */
char *(PASCAL NEAR *tval)(); /* ptr to function to fetch table value with */
int tlength; /* length of table to search */
{
int l, u; /* lower and upper limits of binary search */
int i; /* current search index */
int cresult; /* result of comparison */
/* set current search limit as entire list */
l = 0;
u = tlength - 1;
/* get the midpoint! */
while (u >= l) {
i = (l + u) >> 1;
/* do the comparison */
cresult = strcmp(key, (*tval)(i));
if (cresult == 0)
return(i);
if (cresult < 0)
u = i - 1;
else
l = i + 1;
}
return(-1);
}
char *PASCAL NEAR gtenv(vname)
char *vname; /* name of environment variable to retrieve */
{
register int vnum; /* ordinal number of var refrenced */
static char result[2 * NSTRING]; /* string result */
/* scan the list, looking for the referenced name */
vnum = binary(vname, envval, NEVARS);
/* return errorm on a bad reference */
if (vnum == -1)
return(errorm);
/* otherwise, fetch the appropriate value */
switch (vnum) {
case EVFILLCOL: return(int_asc(fillcol));
case EVPAGELEN: return(int_asc(term.t_nrow + 1));
case EVCURCOL: return(int_asc(getccol(FALSE)));
case EVCURLINE: return(int_asc(getlinenum(curbp, curwp->w_dotp)));
case EVRAM: return(int_asc((int)(envram / 1024l)));
case EVFLICKER: return(ltos(flickcode));
case EVCURWIDTH:return(int_asc(term.t_ncol));
case EVCBFLAGS: return(int_asc(curbp->b_flag));
case EVCBUFNAME:return(curbp->b_bname);
case EVCFNAME: return(curbp->b_fname);
case EVSRES: return(sres);
case EVDEBUG: return(ltos(macbug));
case EVSTATUS: return(ltos(cmdstatus));
case EVPALETTE: return(palstr);
case EVASAVE: return(int_asc(gasave));
case EVACOUNT: return(int_asc(gacount));
case EVLASTKEY: return(int_asc(lastkey));
case EVCURCHAR:
return(curwp->w_dotp->l_used ==
curwp->w_doto ? int_asc('\r') :
int_asc(lgetc(curwp->w_dotp, curwp->w_doto)));
case EVDISCMD: return(ltos(discmd));
case EVVERSION: return(VERSION);
case EVPROGNAME:return(PROGNAME);
case EVLANG: return(LANGUAGE);
case EVSEED: return(int_asc(seed));
case EVDISINP: return(ltos(disinp));
case EVWLINE: return(int_asc(cu